/**
 * Copyright (c) 2008, Chet Haase
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following 
 *     disclaimer in the documentation and/or other materials provided 
 *     with the distribution.
 *   * Neither the name of this project nor the names of its
 *     contributors may be used to endorse or promote products derived 
 *     from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package effects
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.geom.Point;
    
    import mx.core.IFlexDisplayObject;
    import mx.core.IUIComponent;
    import mx.effects.Tween;
    import mx.effects.effectClasses.TweenEffectInstance;
    
    /**
    * This class implements a Spring effect, which will show a 
    * copy of the given UIComponent scaling to 2x and fading out
    * over a specified duration.
    */
    public class SpringInstance extends TweenEffectInstance
    {
        private var component:IUIComponent;
        private var springer:Bitmap;
        private var origX:int, origY:int, origW:int, origH:int;
        private var bmData:BitmapData;
        
        public function SpringInstance(target:Object)
        {
            super(target);
            component = IUIComponent(target);
        }
        
        /**
        * Sets up the animation by creating a temporary "springer" object,
        * which is a bitmap copy of the original component, placing it
        * over the original component, and playing a Tween that will
        * cause us to animate properties of springer.
        */
        override public function play():void
        {
            super.play();

            // Copy the original display object into a bitmap
            bmData = new BitmapData(component.width, component.height, true, 0x000000);
            bmData.draw(component);
            springer = new Bitmap(bmData, "auto", true);
            
            // Get the position of the image on the stage
            var tmpOrigin:Point = new Point(0, 0);
            var origin:Point = component.localToGlobal(tmpOrigin);
            
            springer.x = origin.x;
            springer.y = origin.y;
            
            // These values will be used in later calculations of xy locations
            // of springer as it scales up
            origX = springer.x;
            origY = springer.y;
            origW = springer.width;
            origH = springer.height;
            
            // Set up the animation; it will vary between 0 and 1 over duration ms
            var tween:Tween = new Tween(this, 0, 1, duration);
            if (easingFunction != null) {
            	// The animation will use an easing function if it has been 
            	// set on the effect
                tween.easingFunction = easingFunction;
            }      
            // Add our temporary sprite to the stage
            component.stage.addChild(springer);
        }
        
        /**
        * Our animation is going from 0 to 1 over the duration. We will
        * translate this value to a scale (in both x and y) of 1->2, 
        * a change in the xy location according to the current size,
        * and a fadeout of alpha from 1 to 0.
        */
        override public function onTweenUpdate(value:Object):void
        {
            springer.scaleX = 1 + value;
            springer.scaleY = 1 + value;
            springer.x = origX - (springer.width - origW)/2;
            springer.y = origY - (springer.height - origH)/2;
            springer.alpha = 1 - Number(value);
        }
        
        /**
        * Remove springer from the stage, now that our animation has finished
        * and springer has faded out completely.
        */
        override public function onTweenEnd(value:Object):void
        {
            super.onTweenEnd(value);
            component.stage.removeChild(springer);
            // dispose of the bitmap to release its memory
            bmData.dispose();
        }
    }
}